package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	/**
	 * ...
	 * @author patsup
	 * 
	 * 		This is the main game class.
	 * 		GetSS() is used to access the session's stats.
	 * 		RefreshSessionText() mainly used for testing since it displays all the stats.
	 * 
	 * 		Initialize() resets the game's SessionStats data.
	 * 		ResetRound() resets the round, but maintains the game SessionStats data.
	 * 		
	 **********	Potential issues:
	 * 		EndRound() create a new RoundEnd every round... should just display/undisplay it?
	 * 
	 * *** private functions
	 * DrawBackground():void
	 * 
	 * *** protected functions
	 * BackBtnInputMouseClick():void
	 * 
	 * *** public functions
	 * InitNewGame():void
	 * CleanUpRound():void
	 * ResetRound():void
	 * 
	 * TotalNumPirates():int
	 * NumPirates():int
	 * GetPirateValueAt(i:int):int
	 * GetRoundScore():int
	 * GetPlankValues():int
	 * GetDiceValue():int
	 * 
	 * RemovePlank():void
	 * ReturnPlank():void
	 * EnableDice():void
	 * EnableExecute():void
	 * EnablePirates():void
	 * DisablePirates():void
	 * 
	 * EndRound(roundResult:int):void
	 * ExecuteSubRound():void
	 * 
	 * IncreaseBetSize():void
	 * DecreaseBetSize():void
	 * 
	 * RefreshSessionText():void
	 * GetSS():SessionStats
	 * 
	 */
	public class PGame extends Sprite 
	{
		private const NUMBER_OF_PIRATES:int = 9;
		private const NUMBER_OF_DICE:int = 2;
		private const DICE_MAX_VALUE:int = 6;
		private const COLOR:int = 0xDDEEFF;						//background image parameters
		private const WIDTH:int = 640;
		private const HEIGHT:int = 480;
		private const EXEC_BUTTON_X_STARTLOC:int = 10;			//Button for Execute
		private const EXEC_BUTTON_Y_STARTLOC:int = 150;
		private const ROLL_BUTTON_X_STARTLOC:int = 10;			//Button for Roll
		private const ROLL_BUTTON_Y_STARTLOC:int = 210;
		private const DICE_AREA_X_STARTLOC:int = 200;			//Dice Area
		private const DICE_AREA_Y_STARTLOC:int = 150;
		private const PIRATE_LINEUP_X_STARTLOC:int = 10;		//Pirate Lineup
		private const PIRATE_LINEUP_Y_STARTLOC:int = 25;
		private const PIRATE_PLANK_X_STARTLOC:int = 10;			//Pirate Plank
		private const PIRATE_PLANK_Y_STARTLOC:int = 85;
		private const ROUNDEND_X_STARTLOC:int = 80;				//End of Round screen
		private const ROUNDEND_Y_STARTLOC:int = 65;
		private const BACK_BUTTON_X_STARTLOC:int = 320;			//Button for resign/back to pre-round menu
		private const BACK_BUTTON_Y_STARTLOC:int = 360;
		
		private const SES_STATS_X_STARTLOC:int = 0;			//Session Stats
		private const SES_STATS_Y_STARTLOC:int = 320;
		
		private var diceArea:DiceArea;
		private var execButton:ExecuteButton;
		//private var rollButton:RollButton;
		
		private var pirateLineup:PirateLineup;					//PirateUnits will move between pirateLineup and piratePlank
		private var piratePlank:PiratePlank;
		
		private var roundEnd:RoundEnd;							//end of round screen
		private var sesStats:SessionStats;
		
		private var backButton:MenuButton;						//button to give up/return to pre-round menu
		private var backButtonImgData:ImageData;				//image data to eventually pass to initimage() in menu button
		private const B_BTN_COLOR:int = 0xFF8000;
		private const B_BTN_WIDTH:int = 120;
		private const B_BTN_HEIGHT:int = 40;
		
		private var mainRef:Main;
		
		public function PGame(mainRef:Main):void 
		{
			this.mainRef = mainRef;
			pirateLineup = new PirateLineup(NUMBER_OF_PIRATES, PIRATE_LINEUP_X_STARTLOC, PIRATE_LINEUP_Y_STARTLOC);
			piratePlank = new PiratePlank(PIRATE_PLANK_X_STARTLOC, PIRATE_PLANK_Y_STARTLOC);
			diceArea = new DiceArea(this, NUMBER_OF_DICE, DICE_MAX_VALUE, DICE_AREA_X_STARTLOC, DICE_AREA_Y_STARTLOC);
			execButton = new ExecuteButton(this, EXEC_BUTTON_X_STARTLOC, EXEC_BUTTON_Y_STARTLOC);
			//rollButton = new RollButton(this, ROLL_BUTTON_X_STARTLOC, ROLL_BUTTON_Y_STARTLOC);
			sesStats = new SessionStats(this, SES_STATS_X_STARTLOC, SES_STATS_Y_STARTLOC);
			
			backButtonImgData = new ImageData(BACK_BUTTON_X_STARTLOC, BACK_BUTTON_Y_STARTLOC, "Give Up", B_BTN_COLOR, B_BTN_WIDTH, B_BTN_HEIGHT);
			backButton = new MenuButton(backButtonImgData, BackBtnInputMouseClick);
			
			pirateLineup.SetOtherLocation(piratePlank);		//set locations so they can communicate with each other
			piratePlank.SetOtherLocation(pirateLineup);
			
			DrawBackground();
			addChild(diceArea);
			addChild(pirateLineup);
			addChild(piratePlank);
			addChild(execButton);
			addChild(backButton);
			//addChild(sesStats);	//removed here temporarily?
			//addChild(rollButton);
		}
		
		//DrawBackground()
		//draw a non-interactable background of the game/play area
		private function DrawBackground():void
		{
			graphics.beginFill(COLOR);
			graphics.drawRect(0, 0, WIDTH, HEIGHT);
			graphics.endFill();
		}
		
		//InitNewGame()
		public function InitNewGame():void
		{
			sesStats.InitNewGame();
		}
		//InitLoadGame()
		public function InitLoadGame(data:Object):void
		{
			//sesStats.InitNewGame();
			sesStats.InitLoadGame(data);
		}
		
		//CleanUpRound()
		//called at the end of a round
		public function CleanUpRound():void
		{
			removeChild(roundEnd);
			mainRef.ContinueNewRound();
			
			sesStats.UpdateText();	//here temporarily to see stats
		}
		
		//ResetRound()
		//reset round, continuing game....
		public function ResetRound():void
		{
			pirateLineup.Initialize(NUMBER_OF_PIRATES);
			piratePlank.Initialize();	//to remove any additional pirates just in case...
			diceArea.Initialize();
			execButton.Initialize();
			backButton.EnableButton();	//re-enable back button
			sesStats.UpdateText();
			
			if(mainRef.DEBUG_MODE) addChild(sesStats);	//added here temporarily?
		}
		
		//NumPirates()
		//only returns number of pirates in the lineup, for use in subset() in DiceArea
		//btw, piratePlank should have 0 pirates in it when this is called anyways...
		public function NumPirates():int
		{
			return pirateLineup.NumPirates();
		}
		public function GetPirateValueAt(i:int):int
		{
			return pirateLineup.GetPirateValueAt(i);
		}
		public function GetRoundScore():int
		{
			return pirateLineup.GetPirateValues();
		}
		public function GetPlankValues():int
		{
			return piratePlank.GetPirateValues();
		}
		public function RemovePlank():void
		{
			piratePlank.RemovePirates();
		}
		public function ReturnPlank():void
		{
			piratePlank.ReturnPirates();
		}
		public function GetDiceValue():int
		{
			return diceArea.GetDiceValue();
		}
		public function EnableDice():void
		{
			diceArea.EnableButton();
		}
		public function EnableExecute():void
		{
			execButton.EnableButton();
		}
		public function EnablePirates():void
		{
			pirateLineup.EnableButtons();
		}
		public function DisablePirates():void
		{
			pirateLineup.DisableButtons();
		}
		//public function EnableRoll():void
		//{
			//rollButton.EnableButton();
		//}
		public function EndRound(roundResult:int):void
		{
			if (roundResult == 1)										//1 = round won
			{
				trace("ROUND WON! do end round action");
				roundEnd = new RoundEnd(this, 1, ROUNDEND_X_STARTLOC, ROUNDEND_Y_STARTLOC);
			} else {													//0 = round lost
				trace("<<<<< do end round action >>>>>");
				roundEnd = new RoundEnd(this, 0, ROUNDEND_X_STARTLOC, ROUNDEND_Y_STARTLOC);
			}
			diceArea.DisableButton();
			execButton.DisableButton();
			//rollButton.DisableButton();
			pirateLineup.DisableButtons();
			piratePlank.DisableButtons();
			backButton.DisableButton();
			
			addChild(roundEnd);
			sesStats.ApplyRoundEnd();
			mainRef.SaveGame();			//tell main to save session data to its saveData:SharedObject
		}
		//ExecuteSubRound()
		//at start of each "subround" (rolling dice), increment number of tries and update text
		public function ExecuteSubRound():void
		{
			sesStats.IncrNumTries();
			sesStats.UpdateText();
		}
		public function RefreshSessionText():void
		{
			sesStats.UpdateText();
		}
		
		//BackBtnInputMouseClick()
		//called on back button mouse click
		protected function BackBtnInputMouseClick():void
		{
			backButton.DisableButton();
			buttonMode = false;
			ReturnPlank();
			EndRound(0);
			//mainRef.ContinueNewRound();
		}
		
		public function IncreaseBetSize():void
		{
			sesStats.IncrBetSize();
		}
		public function DecreaseBetSize():void
		{
			sesStats.DecrBetSize();
		}
		public function GetSS():SessionStats
		{
			return sesStats;
		}
		//TotalNumPirates()
		//Need to know this to calculate payout tiers in session stats class
		public function TotalNumPirates():int
		{
			return NUMBER_OF_PIRATES;
		}
		
	}
	
}